using System;
using System.Xml;
using System.Collections;
using System.Runtime.InteropServices;

namespace ScenarioFramework.Modules.PCM.DataModel.ConfigurationManager.Form
{
	//*********************************************************************
	//
	// XMLForms Class
	//
	// The XMLForms class represents a collection base of XMLForm
	// Its imports methods from WAPI.XmlObjectSet like get set and add
	// XMLForms Has no fields
	//
	//*********************************************************************

	public class XMLForms : bOSdotNET.XML.Data.XMLObjectSet 
	{
		public const string MAIN_NODE = "Forms";

		/** FIELDS **/

		/** no fields **/

		/** CONSTRUCTORS **/

		/** CONSTRUCTOR Empty **/
		public XMLForms() 
		{
			this.Init();
		}

		/** CONSTRUCTOR Width xml parsering**/
		public XMLForms(System.Xml.XmlNode nodeList)
		{
			this.Parse (nodeList);
		}

		/** INSTANCE METHODS **/

		override public void Init()
		{
			this.RemoveAll();
		}

		override public void Parse(System.Xml.XmlNode nodeList)
		{
			this.Init();

			System.Xml.XmlNode node;

			for ( int i=0; i<nodeList.ChildNodes.Count;i++)
			{
				node = nodeList.ChildNodes[i];

				switch ( node.Name) 
				{
					case XMLForm.MAIN_NODE:
						this.Add ( new XMLForm(node));
						break;
				}
			}
		}

		/** Method for return a form from collection **/
		public XMLForm Get(string sName)
		{
			XMLForm from;

			for ( int i=0; i<this.List.Count; i++)
			{
				from = (XMLForm)this.List[i];
				if ( from.Name == sName )
				{
					return from;
				}
			}

			throw new Exception.FormNotFound();
		}

		override public bOSdotNET.XML.XMLNode GetXMLNode()
		{
			bOSdotNET.XML.XMLNode xmlNode = new bOSdotNET.XML.XMLNode(XMLForms.MAIN_NODE);

			for ( int i=0; i<this.Count;i++)
			{
				xmlNode.AddNode ( this[i].GetXMLNode() );
			}

			return xmlNode;
		}

		public XMLForm SearchBetterForm(ScenarioFramework.Modules.PCM.DataModel.ConfigurationManager.Entity.XMLEntities vEntities)
		{
			XMLForm form;
			XMLForms formsFound = new XMLForms();

			for ( int i=0; i<this.List.Count; i++)
			{
				form = (XMLForm)this.List[i];

				bool bFormValid = true;
				if ( vEntities.AlmostIn (form.XMLEntities ) )
				{
					for ( int iEntity=0; (iEntity<vEntities.Count) && bFormValid; iEntity++)
					{
						ScenarioFramework.Modules.PCM.DataModel.ConfigurationManager.Entity.XMLEntity entity = (ScenarioFramework.Modules.PCM.DataModel.ConfigurationManager.Entity.XMLEntity)vEntities[iEntity];
						ScenarioFramework.Modules.PCM.DataModel.ConfigurationManager.Entity.XMLEntityAttributes entityAttributes = entity.XMLEntityAttributes;

						ScenarioFramework.Modules.PCM.DataModel.ConfigurationManager.Entity.XMLEntity formEntity = form.XMLEntities.Get(entity.Name);
						ScenarioFramework.Modules.PCM.DataModel.ConfigurationManager.Entity.XMLEntityAttributes formEntityAttributes = formEntity.XMLEntityAttributes;

						if ( entityAttributes.AlmostIn(formEntityAttributes) )
						{
							for ( int iAttribute=0; (iAttribute<entityAttributes.Count) && bFormValid; iAttribute++)
							{
								ScenarioFramework.Modules.PCM.DataModel.ConfigurationManager.Entity.XMLEntityAttribute attribute = (ScenarioFramework.Modules.PCM.DataModel.ConfigurationManager.Entity.XMLEntityAttribute)entityAttributes[iAttribute];
								ScenarioFramework.Modules.PCM.DataModel.ConfigurationManager.Property.XMLProperties attributeProperties = attribute.XMLProperties;

								ScenarioFramework.Modules.PCM.DataModel.ConfigurationManager.Entity.XMLEntityAttribute formAttribute = formEntityAttributes.Get(attribute.Name);
								ScenarioFramework.Modules.PCM.DataModel.ConfigurationManager.Property.XMLProperties formAttributesProperties = formAttribute.XMLProperties;

								if ( attributeProperties.AlmostIn (formAttributesProperties) )
								{
									for ( int iGroupProperties=0; (iGroupProperties<attributeProperties.Count) && bFormValid; iGroupProperties++)
									{
										ScenarioFramework.Modules.PCM.DataModel.ConfigurationManager.Property.XMLPropertiesGroup groupProperty = attributeProperties[iGroupProperties];
										ScenarioFramework.Modules.PCM.DataModel.ConfigurationManager.Property.XMLPropertiesGroup formGroupProperty = formAttributesProperties.Get(groupProperty.sGroup);

										if ( groupProperty.AlmostIn (formGroupProperty) )
										{
											for ( int iProperty=0; (iProperty<groupProperty.Count) && bFormValid ; iProperty++)
											{
												ScenarioFramework.Modules.PCM.DataModel.ConfigurationManager.Property.XMLProperty property = (ScenarioFramework.Modules.PCM.DataModel.ConfigurationManager.Property.XMLProperty)groupProperty[iProperty];
												ScenarioFramework.Modules.PCM.DataModel.ConfigurationManager.Property.XMLPropertyValues propertyValues = property.XMLPropertyValues;

												ScenarioFramework.Modules.PCM.DataModel.ConfigurationManager.Property.XMLProperty formProperty = formGroupProperty.Get(property.Name);
												ScenarioFramework.Modules.PCM.DataModel.ConfigurationManager.Property.XMLPropertyValues formPropertyValues = formProperty.XMLPropertyValues;

												if ( !(propertyValues.AlmostIn (formPropertyValues)) )
													bFormValid = false;
											}
										}
										else
											bFormValid = false;
									}
								}
								else
									bFormValid = false;
							}
						}
						else
							bFormValid = false;
					}

					if ( bFormValid )
					{
						formsFound.Add(form);
					}
				}

			}

			if ( formsFound.Count == 0 ) 
			{
				throw new ScenarioFramework.Modules.PCM.DataModel.ConfigurationManager.Exception.FormNotFound();
			}

			//search better
			//definire un indice.
			return (XMLForm)formsFound[0];
		}



		/** Method for filling the forms widthout calling WAPI first **/
		public void ReadFromConfiguration()
		{
			ScenarioFramework.Modules.PCM.DataModel.ConfigurationManager.PCMWAPIResponse response = new ScenarioFramework.Modules.PCM.DataModel.ConfigurationManager.PCMWAPIResponse();

			String sForms = XMLForms.GetForms(ref response); 

			if ( response.iCode == 0 )
			{
				this.Parse (sForms);
			}
			else
			{
				throw new Exception.ConfigurationError ( response.sMsg);
			}
		}

		[ DllImport( "ConfigurationManager.dll", EntryPoint="GetForms")]
		public static extern string GetForms(ref ScenarioFramework.Modules.PCM.DataModel.ConfigurationManager.PCMWAPIResponse response);

		/** SORTING  FIELDS **/

		public enum SortFields 
		{
			Name,
			Description
		}

		/** SORTING METHODS **/


		public void Sort(SortFields sortField, bool isAscending) 
		{
			switch (sortField) 
			{
				case SortFields.Name:
					InnerList.Sort(new NameComparer());
					break;
				case SortFields.Description:
					InnerList.Sort(new DescriptionComparer());
					break;
				
			}
			if (!isAscending) InnerList.Reverse();
		}


		private sealed class NameComparer : IComparer 
		{
			public int Compare(object x, object y) 
			{
				XMLForm first = (XMLForm) x;
				XMLForm second = (XMLForm) y;
				return first.Name.CompareTo(second.Name);
			}
		}

		private sealed class DescriptionComparer : IComparer 
		{
			public int Compare(object x, object y) 
			{
				XMLForm first = (XMLForm) x;
				XMLForm second = (XMLForm) y;
				return first.Description.CompareTo(second.Description);
			}
		}

		
	}
}